#include "mysql.h"
#include "logger.h"

//mysql_pool_init参数 host user pass dbname
void mysql_pool_init(MysqlPool_t *pool, const char *host, const char *user,
                     const char *pass, const char *dbname) {
    // 初始化互斥锁，用于保护连接池的共享资源，防止多线程同时访问时产生竞态条件
    // 第二个参数为 NULL 表示使用默认的互斥锁属性
    pthread_mutex_init(&pool->lock, NULL);
    // 初始化条件变量，用于线程间的同步，当连接池没有可用连接时，线程可以等待条件变量
    // 第二个参数为 NULL 表示使用默认的条件变量属性
    pthread_cond_init(&pool->cond, NULL);

    // 循环创建指定数量（POOL_SIZE）的 MySQL 连接
    for (int i = 0; i < POOL_SIZE; i++) {
        // 初始化一个新的 MySQL 连接对象
        // mysql_init 函数返回一个指向 MYSQL 结构的指针，若失败则返回 NULL
        pool->connections[i] = mysql_init(NULL);
        // 检查 mysql_init 是否成功
        if (!pool->connections[i]) {
            // 若失败，向标准错误输出错误信息，包含连接编号
            fprintf(stderr, "mysql_init failed for connection %d\n", i);
            // 程序异常退出，返回状态码 1
            exit(1);
        }

        // 尝试建立与 MySQL 服务器的实际连接
        // mysql_real_connect 参数依次为：MYSQL 连接对象、主机名、用户名、密码、数据库名、端口号、套接字文件路径、客户端标志
        if (!mysql_real_connect(pool->connections[i], host, user, pass, dbname, 0, NULL, 0)) {
            // 若连接失败，向标准错误输出错误信息，包含连接编号和具体错误描述
            fprintf(stderr, "mysql_real_connect failed for connection %d: %s\n",
                    i, mysql_error(pool->connections[i]));
            // 程序异常退出，返回状态码 1
            exit(1);
        }

        // 初始化连接状态为未使用，标记该连接可用
        pool->in_use[i] = 0;  
    }
}

MYSQL* mysql_pool_get(MysqlPool_t *pool) {
    pthread_mutex_lock(&pool->lock);

    while (1) {
        for (int i = 0; i < POOL_SIZE; i++) {
            if (!pool->in_use[i]) {
                pool->in_use[i] = 1;  // 标记为使用中
                pthread_mutex_unlock(&pool->lock);
                return pool->connections[i];
            }
        }

        // 如果没有可用连接，则等待其他线程释放
        pthread_cond_wait(&pool->cond, &pool->lock);
    }
}

void mysql_pool_release(MysqlPool_t *pool, MYSQL *conn) {
    pthread_mutex_lock(&pool->lock);
    for (int i = 0; i < POOL_SIZE; i++) {
        if (pool->connections[i] == conn) {
            pool->in_use[i] = 0;               // 标记为可用
            pthread_cond_signal(&pool->cond);  // 通知等待的线程
            break;
        }
    }
    pthread_mutex_unlock(&pool->lock);
}

void mysql_pool_destroy(MysqlPool_t *pool) {
    for (int i = 0; i < POOL_SIZE; i++) {
        mysql_close(pool->connections[i]);
    }
    pthread_mutex_destroy(&pool->lock);
    pthread_cond_destroy(&pool->cond);
}
